/*
 * Copyright (C) 2017-2018 Alibaba Group Holding Limited. All Rights Reserved.
 *
 *
 * Licensed under the Apache License, Version 2.0 (the License);
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef ALIOS_LOCAL_TTS_H_
#define ALIOS_LOCAL_TTS_H_

#include <stdint.h>
#include <string>
#include "tts_listener.h"

/**
* @file local_tts.h
* @brief This file contains TTSEngine public interface defined by AliOS,
* and is shared by the platform independent voice framework and the vendor specific Implementation.
***/

namespace alios {

typedef enum {
  TtsEncodePcm = 0,
} TTSEncodeType;

typedef enum {
  TtsDebugNone = 0,
  TtsDebugLog = 1,
  TtsDebugWave = 2,
} TTSDebugMode;

typedef enum {
  TtsTimeLabelNone = 0,
  TtsTimeLabelNum = 1,
  TtsTimeLabelText = 2,
} TTSTimeLabelType;

typedef enum {
  TtsHts = 0,
  TtsNus = 1,
  TtsRus = 2,
} TTSMethodType;

typedef enum {
  TtsRetOk = 0,
  TtsRetNoData = 1,
  TtsRetStartFailed = 2,
  TtsRetTaskNotExist = 3,
  TtsRetNewFailed = 4,
  TtsRetUnsupport = 5,
} TTSRetCode;

const int TTSDefaultSampleRate = 22050;  // default sample rate for tts service
const int TTSFetchDataMaxLen = 24044;
const int TTSTextLabelMaxLen = 3200;

class TTSLocalEngine {
public:
  TTSLocalEngine() {}
  virtual ~TTSLocalEngine() {}
  /**
   * @brief get the version of TTSLocalEngine.
   * @return tts engine version
   */
  virtual const char *GetVersion() = 0;
  /**
   * @brief initialize tts engine and create tts running context.
   * @note all tts tasks will be running in same tts context.
   * @param[assets_path] 3rd tts engine's resource path
   * @param[uuid] machine unique ID
   * @return tts engine context
   */
  virtual void *CreateContext(const std::string &assets_path, const std::string &output_path, const std::string &uuid) = 0;
  /**
   * @brief release tts engine context
   * @param[context] tts engine context
   */
  virtual void ReleaseContext(void *context) = 0;
  /**
   * @brief Create tts task for playing concurrent tts
   * @param[context] tts engine context from CreateContext interface
   * @param[sample_rate] tts audio sample rate, default is 16000
   * @param[encode_type] tts encode type, default is pcm
   * @return tts engine task
   */
  virtual void *CreateTask(void *context, int sample_rate, TTSEncodeType encode_type) = 0;
  /**
   * @brief Start to synthesize the text according the following params: fond id, speech level, pitch level
   * @param[task] tts engine task
   * @param[text] tts string
   * @param[font_id] tts font id
   * @param[speed_level] tts speed level
   * @param[pitch_level] tts pitch level
   * @return return TTSLocalEngine result for Start.
   */
  virtual TTSRetCode Start(void *task, const char *text) = 0;
  /**
   * @brief fetch tts audio data from tts engine
   * @param[task] in param, tts engine task
   * @param[output_data] in param, tts audio data
   * @param[data_length] in param, tts audio data's length
   * @param[word_idx] out param, return the word index of the whole text
   * @param[output_text] out param, return the text of the current audio data
   * @return return TTSLocalEngine result for FetchData.
   */
  virtual TTSRetCode FetchData(void *task, char *output_data, int &data_length, int &word_idx, char *output_text) = 0;
  /**
   * @brief stop to synthesize tts
   * @param[task] tts engine task
   * @return return TTSLocalEngine result for Stop.
   */
  virtual TTSRetCode Stop(void *task) = 0;
  /**
   * @brief release tts task
   * @param[task] tts engine task
   * @return return TTSLocalEngine result for ReleaseTask.
   */
  virtual TTSRetCode ReleaseTask(void *task) = 0;
  /**
   * @brief set debug mode
   * @param[task] tts engine task
   * @param[debug_mode] debug mode: TtsDebugNone, TtsDebugLog, TtsDebugWave
   * @param[save_path] tts debug log path
   */
  virtual void SetDebugMode(void *task, TTSDebugMode debug_mode, const char *save_path) = 0;
  /**
    * @brief set TTSLocalEngineListener listener for notify tts info
    * @param[task] tts engine task
    * @param[listener] TTSLocalEngineListener is for receiving notify message
    * listener can be null or one customed object of subclass TTSLocalEngineListener.
    */
   virtual void SetListener(void *task, TTSEngineListener *listener) = 0;
    /**
    * @brief set TTSLocalEngineListener listener for notify tts info
    * @param[listener] TTSLocalEngineListener is for receiving notify message
    * listener can be null or one customed object of subclass TTSLocalEngineListener.
    */
   virtual void SetListener(TTSEngineListener *listener) = 0;
    /**
    * @brief set default oem tts voice id
    * @note
    * @param[voice_id] default oem voice id
    * @return success return 0，fail return -1
    */
    virtual TTSRetCode SetVoiceId(void *task, int voice_id) = 0;
    /**
    * @brief set user tts voice id
    * @note
    * @param[user_voice_path] user tts path
    * @return success return 0，fail return -1
    */
    virtual TTSRetCode SetVoiceId(void *task, const std::string &user_voice_path) = 0;
    /**
    * @brief set tts volume
    * @note The range is 0~100, default is 50
    * @param volume value
    * @return success return 0，fail return -1
    */
    virtual TTSRetCode SetVolume(void *task, int value) = 0;
    /**
    * @brief set tts speech rate
    * @note The range is 0~2, default is 1, correspond to：fast、normal、slow
    * @param speech rate value
    * @return success return 0，fail return -1
    */
    virtual TTSRetCode SetSpeechRate(void *task, int value) = 0;
    /**
    * @brief set tts pitch rate
    * @note The range is -500~500, default is 0
    * @param pitch value
    * @return success return 0，fail return -1
    */
    virtual TTSRetCode SetPitchRate(void *task, int value) = 0;
};

}  // namespace alios

#if __GNUC__ >= 4
#  define TTS_EXPORT_API __attribute__ ((visibility ("default")))
#  define TTS_IMPORT_API __attribute__ ((visibility ("default")))
#  define TTS_INTERNAL   __attribute__ ((visibility ("hidden")))
#else
/** Visibility attribute to show method definitions */
#  define TTS_EXPORT_API
/** Visibility attribute to show declarations */
#  define TTS_IMPORT_API
/** Visibility attribute to hide declarations */
#  define TTS_INTERNAL
#endif

#define TTS_CREATEENGINE_SYM "TTS_CreateLocalEngine"
#define TTS_DESTROYENGINE_SYM "TTS_DestroyLocalEngine"

/*----------------------------------------------------------------------*/
/*                        Function Prototypes                           */
/*----------------------------------------------------------------------*/
#ifdef __cplusplus
extern "C" {
#endif

//
// TTS Engine library default entry points.
// TTS_CreateLocalEngine/TTS_DestroyLocalEngine.
//


typedef alios::TTSLocalEngine* (*TTS_CreateLocalEngineFunc)(const char *assets_path);
typedef alios::TTSRetCode (*TTS_DestroyLocalEngineFunc)(alios::TTSLocalEngine* engine);

#ifdef __cplusplus
}  /* end extern "C" */
#endif

#endif  // ALIOS_LOCAL_TTS_H_
